AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
util.PrecacheSound( "ambient.steam01" )

include('shared.lua')

local Ground = 1 + 0 + 2 + 8 + 32

function ENT:Initialize()
	self.Entity:PhysicsInit( SOLID_VPHYSICS )
	self.Entity:SetMoveType( MOVETYPE_VPHYSICS )
	self.Entity:SetSolid( SOLID_VPHYSICS )
	
	local phys = self.Entity:GetPhysicsObject()
	self.val1 = 0
	self.val2 = 0
	self.val3 = 0
	self.val4 = 0
	self.vent = 0
	self.sounded = 0
	self.dir = Vector(0,0,0)
	self.damaged = 0
	LS_RegisterEnt(self.Entity)

	if not (WireAddon == nil) then self.Inputs = Wire_CreateInputs(self.Entity, { "Vent Container" }) end
	if not (WireAddon == nil) then self.Outputs = Wire_CreateOutputs(self.Entity, { "Air", "Energy", "Coolant", "Hydrogen", "Max Air", "Max Energy" , "Max Coolant", "Max Hydrogen" }) end
	
	self.timer = CurTime() +  1
	if (phys:IsValid()) then
		phys:Wake()
	end
end

function ENT:TriggerInput(iname, value)
	if (iname == "Vent Container") then
		if (value ~= 0) then
			if ( self.vent == 0 ) then
				self.vent = 1
			end
		else
			if ( self.vent == 1 ) then
				self.vent = 0
			end
		end
	end
end

function ENT:Damage()
	if (self.damaged == 0) then
		self.damaged = 1
		self.Entity:EmitSound( "PhysicsCannister.ThrusterLoop" )
		self.Entity:EmitSound( "ambient.steam01" )
		self.dir = Vector(math.random(-999999, 999999), math.random(-999999, 999999), math.random(-999999, 999999))
	end
end

function ENT:Repair()
	self.Entity:SetColor(255, 255, 255, 255)
	self.health = self.max_health
	self.damaged = 0
	self.Entity:StopSound( "PhysicsCannister.ThrusterLoop" )
	self.Entity:StopSound( "ambient.steam01" )
end

function ENT:Destruct()
	local Effect = EffectData()
		Effect:SetOrigin(self.Entity:GetPos())
		Effect:SetScale(1)
		Effect:SetMagnitude(25)
		util.Effect("Explosion", Effect, true, true)
	doempspark(self.Entity:GetPos()+Vector(0,0,50),10)
	doempspark(self.Entity:GetPos(),10)
	doempspark(self.Entity:GetPos()+Vector(0,50,0),10)
	doempspark(self.Entity:GetPos()+Vector(50,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(-50,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-50,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,-50),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,50),10)


	doempspark(self.Entity:GetPos()+Vector(0,300,0),10)
	doempspark(self.Entity:GetPos()+Vector(300,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(-300,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-300,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,-300),10)

	doempspark(self.Entity:GetPos()+Vector(0,500,0),10)
	doempspark(self.Entity:GetPos()+Vector(500,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(-500,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-500,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,-500),10)

	doempspark(self.Entity:GetPos()+Vector(0,800,0),10)
	doempspark(self.Entity:GetPos()+Vector(800,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(-800,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-800,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,-800),10)

	doempspark(self.Entity:GetPos()+Vector(0,1000,0),10)
	doempspark(self.Entity:GetPos()+Vector(1000,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(-1000,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-1000,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,-1000),10)

	doempspark(self.Entity:GetPos()+Vector(0,1500,0),10)
	doempspark(self.Entity:GetPos()+Vector(1500,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(-1500,0,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-1500,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,0,-1500),10)
	
	doempspark(self.Entity:GetPos()+Vector(0,1500,1500),10)
	doempspark(self.Entity:GetPos()+Vector(1500,1500,0),10)
	doempspark(self.Entity:GetPos()+Vector(1500,0,1500),10)
	doempspark(self.Entity:GetPos()+Vector(-1500,-1500,0),10)
	doempspark(self.Entity:GetPos()+Vector(0,-1500,0),10)
	doempspark(self.Entity:GetPos()+Vector(-1500,0,-1500),10)
	doempspark(self.Entity:GetPos()+Vector(0,-1500,-1500),10)
	if RD_GetResourceAmount(self, "energy") > 0 then
		for k,v in pairs(ents.FindInSphere(self.Entity:GetPos(),math.Round(RD_GetResourceAmount(self, "energy")))) do --emp shockwave
			empattack(self.Entity:GetVar("Owner"),v,math.Round(math.sqrt(RD_GetResourceAmount(self, "energy"))))
			--ohshit
		end
		local ball = ents.Create("prop_combine_ball")
		ball:SetPos(self.Entity:GetPos())
		ball:Fire("explode", "", 0) 
	end
	if (self.environment.atmosphere > 0) then 
		util.BlastDamage(self.Entity,self.Entity,self.Entity:GetPos(),math.Round(math.sqrt(RD_GetResourceAmount(self, "hydrogen"))),math.Round((RD_GetResourceAmount(self, "hydrogen")/2)*self.environment.atmosphere))--BOOM!
	end
		self.Entity:Remove()
end

function ENT:OnRemove()
	Dev_Unlink_All(self.Entity)
	self.Entity:StopSound( "PhysicsCannister.ThrusterLoop" )
	self.Entity:StopSound( "ambient.steam01" )
end




function ENT:Output()
	return 1
end



function ENT:Think()
	self:SetOverlayText( "Air: " .. self.val1 .. "\nEnergy: " .. self.val2 .. "\nCoolant: " .. self.val3 .. "\nHydrogen: " .. self.val4)
	if ( self.timer > CurTime() ) then return end
	
	local air = RD_GetResourceAmount(self, "air")
	local energy = RD_GetResourceAmount(self, "energy")
	local coolant = RD_GetResourceAmount(self, "coolant")
	local hydrogen = RD_GetResourceAmount(self, "hydrogen")
	local mair = RD_GetNetworkCapacity(self, "air")	
	local mcoolant = RD_GetNetworkCapacity(self, "coolant")
	local menergy = RD_GetNetworkCapacity(self, "energy")
	local mhydrogen = RD_GetNetworkCapacity(self, "hydrogen")


	self.val1 = air
	self.val2 = energy
	self.val3 = coolant
	self.val4 = hydrogen
	
	if self.vent == 1 then --MAYDAY! VENT THE CONTAINER! (lol)
		RD_ConsumeResource(self, "air", self.val1);
		RD_ConsumeResource(self, "coolant", self.val3);
		RD_ConsumeResource(self, "hydrogen", self.val4);
		if self.sounded == 0 then
			self.Entity:EmitSound( "PhysicsCannister.ThrusterLoop" )
			self.Entity:EmitSound( "ambient.steam01" )
			self.sounded = 1
		end
		--you can only vent power in water.
		local entpos = self.Entity:GetPos()
		if (self.environment.inwater == 1) then
			RD_ConsumeResource(self, "energy", self.val2);
			local pos = (self.Entity:GetPos() + (self.Entity:GetAngles():Up() * self.Entity:BoundingRadius()))
			zapme(pos, 1)
			local tAllPlayers = player.GetAll()
			for _, pPlayer in pairs( tAllPlayers ) do
				if (pPlayer.suit.inwater == 1) then
					if (self.Entity:GetPos():Distance(pPlayer.Entity:GetPos()) < 600) then
						local pos2 = (pPlayer.Entity:GetPos() + (pPlayer.Entity:GetAngles():Forward() * 10))
						zapme(pos2, 1)
						pPlayer.Entity:TakeDamage( (self.val2 / 100), 0 )
					end
				end
			end
			self:Destruct()
		end
	elseif (self.sounded == 1 and self.vent == 0) then
		self.Entity:StopSound( "PhysicsCannister.ThrusterLoop" )
		self.Entity:StopSound( "ambient.steam01" )
		self.sounded = 0
	end
	
	if (self.damaged == 1) then
		if (air > 0) then
			local rnd = math.random(0,500)
			if (air >= rnd) then
				RD_ConsumeResource(self, "air", rnd)
				self.Entity:GetPhysicsObject():ApplyForceOffset(Vector(0,0,rnd*1000), self.dir)
			else
				RD_ConsumeResource(self, "air", air)
				self.Entity:StopSound( "PhysicsCannister.ThrusterLoop" )
				self.Entity:GetPhysicsObject():ApplyForceOffset(Vector(0,0,air*1000), self.dir)
			end
		end
		if (energy > 0) then
			local entpos = self.Entity:GetPos()
			if (self.environment.inwater == 1) then
				local pos = (self.Entity:GetPos() + (self.Entity:GetAngles():Up() * self.Entity:BoundingRadius()))
				zapme(pos, 1)
				local tAllPlayers = player.GetAll()
				NextUpdateTime = CurTime() + 1
				for _, pPlayer in pairs( tAllPlayers ) do
					if (pPlayer.suit.inwater == 1) then
						if (self.Entity:GetPos():Distance(pPlayer.Entity:GetPos()) < 600) then
							local pos2 = (pPlayer.Entity:GetPos() + (pPlayer.Entity:GetAngles():Forward() * 10))
							zapme(pos2, 1)
							pPlayer.Entity:TakeDamage( (energy / 100), 0 )
						end
					end
				end
				max_energy = RD_GetUnitCapacity(self, "energy")
				if (energy >= max_energy) then
					RD_ConsumeResource(self, "energy", max_energy)
				else
					RD_ConsumeResource(self, "energy", energy)
				end
			else
				if (math.random(1, 10) < 2) then
					local pos = (self.Entity:GetPos() + (self.Entity:GetAngles():Up() * self.Entity:BoundingRadius()))
					zapme(pos, 1)
					local dec = math.random(200, 2000)
					if (energy > dec) then
						RD_ConsumeResource(self, "energy", dec)
					else
						RD_ConsumeResource(self, "energy", energy)
					end
				end
			end
		end
		if (coolant > 0) then
			if (coolant >= 100) then
				RD_ConsumeResource(self, "coolant", 100)
			else
				RD_ConsumeResource(self, "coolant", air)
				self.Entity:StopSound( "ambient.steam01" )
			end
		end
		if (hydrogen > 0) then
			local rnd = math.random(0,500)
			if (hydrogen >= rnd) then
				RD_ConsumeResource(self, "hydrogen", rnd)
				self.Entity:GetPhysicsObject():ApplyForceOffset(Vector(0,0,rnd*1000), self.dir)
			else
				RD_ConsumeResource(self, "hydrogen", hydrogen)
				self.Entity:StopSound( "PhysicsCannister.ThrusterLoop" )
				self.Entity:GetPhysicsObject():ApplyForceOffset(Vector(0,0,hydrogen*1000), self.dir)
			end
		end
	end
	
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Air", air) end
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Energy", energy) end
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Coolant", coolant) end
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Hydrogen", hydrogen) end 
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Max Air", mair) end 
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Max Energy", menergy) end 
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Max Coolant", mcoolant) end
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Max Hydrogen", mhydrogen) end 

	self.timer = CurTime() +  1
end

function ENT:PreEntityCopy()
	RD_BuildDupeInfo(self.Entity)
	if (WireAddon == 1) then
		local DupeInfo = Wire_BuildDupeInfo(self.Entity)
		if DupeInfo then
			duplicator.StoreEntityModifier( self.Entity, "WireDupeInfo", DupeInfo )
		end
	end
end

function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
	RD_ApplyDupeInfo(Ent, CreatedEntities)
	if (WireAddon == 1) then
		if (Ent.EntityMods) and (Ent.EntityMods.WireDupeInfo) then
			Wire_ApplyDupeInfo(Player, Ent, Ent.EntityMods.WireDupeInfo, function(id) return CreatedEntities[id] end)
		end
	end
end
